﻿using System;
using System.Threading.Tasks;
using FwProject.Distribution.Dto;
using Microsoft.AspNetCore.Mvc;
using FwProject.Distribution;
using X.PagedList;
using Abp.Runtime.Caching;
using Abp.Domain.Repositories;
using Abp.ObjectMapping;
using Abp;
using System.Collections.Generic;
using System.Linq;
using AutoMapper.QueryableExtensions;
using FwProject.Core.Restaurant;
using FwProject.Core.Distribution;
using FwProject.Core.Car;
using FwProject.Manager;
using Abp.Authorization;
using FwProject.TypeNumber;
using FwProject.Restaurant;
using FwProject.Users;
using FwProject.PublicService.SqlExec;
using FwProject.Core.TypeNumber;
using FwProject.Core.SettlementInfoModel;
using FwProject.Authorization.Users;

namespace FwProject.Distribution
{
    [AbpAuthorize]
    public class DistributionDetailsAppService : FwProjectAppServiceBase, IDistributionDetailsAppService
    {

        public readonly IRepository<DistributionInfoDetails, Guid> _repositoryDistributionInfoDetails;
        public readonly IRepository<RestaurantInfo, Guid> _repositoryRestaurantInfo;
        public readonly IRepository<RestaurantTypenNumberInfo, Guid> _repositoryRestaurantTypenNumberInfo;
        public readonly IRepository<DistributionInfo, Guid> _repositoryDistributionInfo;
        public readonly IRepository<CarInfo, Guid> _repositoryCarInfo;
        public readonly IRepository<LoadCar, Guid> _repositoryLoadCar;
        public readonly IRepository<TypeNumberInfo, Guid> _repositoryTypeNumber;
        public readonly IRepository<SettlementInfo, Guid> _repositorySettlement;
        public readonly IRepository<User, long> _repositoryUser;
        private readonly IRestaurantTypeNumberAppService _IRestaurantTypeNumberAppService;
        private readonly IUserAppService _userAppService;
        private readonly ISqlExecuter _sqlExecuter;
        private readonly DistributionInfoDetailsManager _distributionInfoDetailsManager;
        public readonly ICacheManager _catchmanager;
        public IGuidGenerator _guid { get; set; }
        public IObjectMapper _map { get; set; }
        public DistributionDetailsAppService(
               ICacheManager catchmanager, IRepository<RestaurantInfo, Guid> repositoryRestaurantInfo,
               IRepository<DistributionInfoDetails, Guid> repositoryDistributionInfoDetails,
               IRepository<RestaurantTypenNumberInfo, Guid> repositoryRestaurantTypenNumberInfo,
               IRepository<DistributionInfo, Guid> repositoryDistributionInfo,
               IRepository<CarInfo, Guid> repositoryCarInfo, IUserAppService userAppService,
               IRepository<LoadCar, Guid> repositoryLoadCar, DistributionInfoDetailsManager distributionInfoDetailsManager,
               IRestaurantTypeNumberAppService iRestaurantTypeNumberAppService, ISqlExecuter sqlExecuter, IRepository<TypeNumberInfo, Guid> repositoryTypeNumber,
               IRepository<SettlementInfo, Guid> repositorySettlement, IRepository<User, long> repositoryUser)
        {
            _repositoryTypeNumber = repositoryTypeNumber;
            _IRestaurantTypeNumberAppService = iRestaurantTypeNumberAppService;
            _catchmanager = catchmanager;
            _repositoryRestaurantInfo = repositoryRestaurantInfo;
            _repositoryDistributionInfoDetails = repositoryDistributionInfoDetails;
            _repositoryRestaurantTypenNumberInfo = repositoryRestaurantTypenNumberInfo;
            _repositoryDistributionInfo = repositoryDistributionInfo;
            _repositoryCarInfo = repositoryCarInfo;
            _repositoryLoadCar = repositoryLoadCar;
            _repositorySettlement = repositorySettlement;
            _repositoryUser = repositoryUser;
            _userAppService = userAppService;
            _distributionInfoDetailsManager = distributionInfoDetailsManager;
            _sqlExecuter = sqlExecuter;
            _guid = SequentialGuidGenerator.Instance;
        }
        /// <summary>
        /// 创建一个配送明细
        /// </summary>
        /// <returns>The create.</returns>
        /// <param name="input">Input.</param>
        public async Task<Guid> Create(DistributionDetailsInputDto input)
        {
            var typeNumber = await _repositoryTypeNumber.GetAsync(input.TypeNumberInfoId.Value);
            var model = _map.Map<DistributionInfoDetails>(input);
            model.Id = _guid.Create();
            model.TypeNumberName = typeNumber.Name;
            return await _distributionInfoDetailsManager.CreateDistributionDetail(model);
        }

        /// <summary>
        /// 获取配送明细信息
        /// </summary>
        /// <returns>The by identifier async.</returns>
        /// <param name="id">Identifier.</param>
        public async Task<DistributionDetailsDto> GetByIdAsync(Guid id)
        {

            var model = await _repositoryDistributionInfoDetails.GetAsync(id);
            return _map.Map<DistributionDetailsDto>(model);

        }
        /// <summary>
        /// 获取该餐厅的所有配送求和
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int GetTypeNumberCount(Guid id)
        {
            var model = _repositoryRestaurantInfo.Get(id);
            return model.RealStock;
        }
        /// <summary>
        /// 根据配送id 获取配送明细
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<List<DistributionDetailsDto>> GetDistributionByIdAsync(Guid id)
        {
            var model = await _repositoryDistributionInfoDetails.GetAllIncluding(o => o.TypeNumberInfoModel, o => o.RestaurantTypenNumberInfoModel).Where(o => o.DistributionInfoId == id).ToListAsync();
            //var model = await _repositoryDistributionInfoDetails.GetAsync(id);
            var data = _map.Map<List<DistributionDetailsDto>>(model);
            return data;

        }

        public async Task<List<DistributionDetailsOutInputDto>> GetDistributionDetailsBySettlementIdAsync(Guid settlementId)
        {
            var settlement = await _repositorySettlement.GetAsync(settlementId);

            if (settlement.BalanceWayEnum == BalanceWayEnum.日结)
            {
                return await _repositoryDistributionInfoDetails.GetAllIncluding(o => o.TypeNumberInfoModel).Where(o => o.PricesId == settlementId).Select(o => new DistributionDetailsOutInputDto
                {
                    TypeNumberName = o.TypeNumberName,
                    Distributioncount = o.Distributioncount,
                    Recoverycount = o.Recoverycount,
                    Exchangegoodscount = o.Exchangegoodscount,
                    Damagecount = o.Damagecount,
                    Givecount = o.Givecount,
                    Backboxcount = o.Backboxcount,
                    Backnumbercount = o.Backnumbercount,
                    Pricestatus = o.Pricestatus,
                    TypeNumberPrice = o.TypeNumberPrice,
                    SumPrice = o.Sumprice
                }).ToListAsync();
            }
            else
            {
                var list = _repositoryDistributionInfoDetails.GetAllIncluding(o => o.TypeNumberInfoModel).Where(o => o.PricesId == settlementId).AsQueryable();
                //var list =  model.ProjectTo<DistributionDetailsDto>().ToList();

                var data = list.GroupBy(o => o.TypeNumberInfoId).Select(a => new DistributionDetailsOutInputDto
                {
                    TypeNumberName = a.First().TypeNumberName,
                    SumDistributionBoxCount = a.Sum(b => b.Distributioncount),
                    SumDistributionCount = a.Sum(b => b.Distributioncount) * a.First().TypeNumberInfoModel.Count,
                    TypeNumberPrice = a.First().TypeNumberPrice,
                    SumPrice = a.Sum(b => b.Sumprice)
                });

                return data.ToList();
            }
        }
        /// <summary>
        /// 打印配送明细
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public List<DistributionDetailsPrintDto> GetDistributionDetailsPrintList(Guid[] ids)
        {
            List<DistributionDetailsPrintDto> list = new List<DistributionDetailsPrintDto>();
            foreach (var id in ids)
            {
                var data = _repositoryDistributionInfoDetails.GetAllIncluding(o => o.TypeNumberInfoModel).Where(o => o.PricesId == id).AsQueryable();

                var groupData = data.GroupBy(o => new { o.TypeNumberInfoId, o.TypeNumberInfoModel, o.TypeNumberName, o.TypeNumberPrice, o.CreatorUserId }).Select(x => new
                {
                    x.Key.TypeNumberName,
                    x.Key.TypeNumberPrice,
                    x.Key.CreatorUserId,
                    DistributionBoxCount = x.Sum(y => y.Distributioncount),
                    DistributionCount = x.Sum(y => y.Distributioncount * x.Key.TypeNumberInfoModel.Count),
                    RecoveryBoxCount = x.Sum(y => y.Recoverycount),
                    RecoveryCount = x.Sum(y => y.Recoverycount * x.Key.TypeNumberInfoModel.Count),
                    BackBoxCount = x.Sum(y => y.Backboxcount),
                    BackCount = x.Sum(y => y.Backnumbercount),
                    ExchangeBoxCount = x.Sum(y => y.Exchangegoodscount),
                    GiveBoxCount = x.Sum(y => y.Givecount),
                    DamageCount = x.Sum(y => y.Damagecount),
                    SumPrice = x.Sum(y => y.Sumprice)
                }).Join(_repositoryUser.GetAll(), a => a.CreatorUserId, b => b.Id, (a, b) => new DistributionDetailsPrintDto
                {
                    TypeNumberName = a.TypeNumberName,

                    DistributionBoxCount = a.DistributionBoxCount,
                    DistributionCount = a.DistributionCount,
                    BackBoxCount = a.BackBoxCount,
                    BackCount = a.BackCount,
                    RecoveryBoxCount = a.RecoveryBoxCount,
                    RecoveryCount = a.RecoveryCount,
                    ExchangeBoxCount = a.ExchangeBoxCount,
                    GiveBoxCount = a.GiveBoxCount,
                    DamageCount = a.DamageCount,
                    TypeNumberPrice = a.TypeNumberPrice,
                    SumPrice = a.SumPrice
                });

                foreach (var item in groupData)
                {
                    DistributionDetailsPrintDto dto = new DistributionDetailsPrintDto();
                    dto.TypeNumberName = item.TypeNumberName;

                    dto.DistributionBoxCount = item.DistributionBoxCount;
                    dto.DistributionCount = item.DistributionCount;
                    dto.RecoveryBoxCount = item.RecoveryBoxCount;
                    dto.RecoveryCount = item.RecoveryCount;
                    dto.BackBoxCount = item.BackBoxCount;
                    dto.BackCount = item.BackCount;
                    dto.ExchangeBoxCount = item.ExchangeBoxCount;
                    dto.GiveBoxCount = item.GiveBoxCount;
                    dto.DamageCount = item.DamageCount;
                    dto.TypeNumberPrice = item.TypeNumberPrice;
                    dto.SumPrice = item.SumPrice;

                    list.Add(dto);
                }
            }
            return list;
        }

        public async Task<List<DistributionDetailsListDto>> GetByIdDistributionDetailsListAsync(Guid id)
        {
            var model = _repositoryDistributionInfoDetails.GetAllIncluding(o => o.TypeNumberInfoModel, o => o.RestaurantTypenNumberInfoModel).Where(o => o.DistributionInfoId == id);
            if (model == null)
                throw new Abp.UI.UserFriendlyException("没有找到配送记录");
            List<DistributionDetailsListDto> list = new List<DistributionDetailsListDto>();

            try
            {
                list = await model.Select(o => new DistributionDetailsListDto()
                {
                    Id = o.Id,
                    Restaurantid = o.Restaurantid,
                    TypeNumberInfoId = o.TypeNumberInfoId.Value,
                    TypeNumberName = o.TypeNumberInfoModel.Name,
                    Price = o.TypeNumberPrice,
                    Count = o.TypeNumberInfoModel.Count,
                    Distributioncount = o.Distributioncount,
                    DistributionBycount = o.Distributioncount * o.TypeNumberInfoModel.Count,
                    Recoverycount = o.Recoverycount,
                    RecoveryBycount = o.Recoverycount * o.TypeNumberInfoModel.Count,
                    Damagecount = o.Damagecount,
                    Exchangegoodscount = o.Exchangegoodscount,
                    ExchangegoodsBycount = o.Exchangegoodscount * o.TypeNumberInfoModel.Count,
                    Givecount = o.Givecount,
                    GiveBycount = o.Givecount * o.TypeNumberInfoModel.Count,
                    Backboxcount = o.Backboxcount,
                    Backnumbercount = o.Backnumbercount,
                    Pricestatus = o.Pricestatus,
                    Sumprice = o.Sumprice,
                    DistributionInfoId = o.DistributionInfoId.Value
                }).ToListAsync();

            }
            catch (Exception e)
            {
                Logger.Error("产品型号已删除", e);
                throw new Abp.UI.UserFriendlyException("产品型号不存在");
            }
            return list;
        }

        /// <summary>
        /// 配送明细列表
        /// </summary>
        /// <returns>The restaurant paged list async.</returns>
        /// <param name="配送编号">Page index.</param>
        public async Task<IPagedList<DistributionDetailsDto>> GetPagedListAsync(Guid id)
        {

            var model = (await GetCache).AsQueryable().Where(o => o.DistributionInfoId == id);
            return await model.ProjectTo<DistributionDetailsDto>().ToPagedListAsync(1, 10);

        }
        public async Task<List<DistributionDetailsDto>> GetDistributionDetailsDtoListAsync(Guid id)
        {

            var model = (await GetCache).AsQueryable().Where(o => o.DistributionInfoId == id).ToList();
            var t = _map.Map<List<DistributionDetailsDto>>(model);
            //修改原有的不足处
            //foreach (var item in t)
            //{
            //    item.TypeNumberName = (await _IRestaurantTypeNumberAppService.GetByIdAsync(item.RestaurantTypenNumberInfoId)).TypeNumberInfoModel.Name;
            //}
            return t;
        }
        /// <summary>
        /// 修改配送明细
        /// </summary>
        /// <returns>The update.</returns>
        /// <param name="id">Identifier.</param>
        /// <param name="input">Input.</param>
        public async Task Update(Guid id, DistributionDetailsInputDto input)
        {
            var model = await _repositoryDistributionInfoDetails.GetAsync(id);
            model = _map.Map(input, model);
            await _distributionInfoDetailsManager.UpdateDistributionDetail(model);

        }
        /// <summary>
        /// 根据配送ID修改配送价格
        /// </summary>
        /// <param name="id"></param>
        /// <param name="price"></param>
        /// <returns></returns>
        public async Task UpdatePrice(Guid id, decimal price)
        {
            var model = await _repositoryDistributionInfoDetails.GetAsync(id);
            model.Sumprice = price;
            await _distributionInfoDetailsManager.UpdateDistributionDetail(model);
        }
        /// <summary>
        /// 配送货品统计
        /// </summary>
        /// <param name="pageIdx"></param>
        /// <param name="pageSize"></param>
        /// <param name="beginTime"></param>
        /// <param name="endTime"></param>
        /// <param name="restaurantName"></param>
        /// <param name="driverName"></param>
        /// <returns></returns>
        public async Task<IPagedList<DistributionTypeNumberReportDto>> GetDistributionDetailsListAsync(int pageIdx, int pageSize, DateTime? beginTime, DateTime? endTime, string restaurantName, long? driverName)
        {
            #region sql
            //var where1 = "";
            //var where2 = "";
            //if (beginTime.HasValue)
            //{
            //    where1 = " where CreationTime>='" + beginTime + "'";
            //}
            //if (endTime.HasValue)
            //{
            //    endTime = endTime.Value.AddHours(24);
            //    where2 = " and CreationTime<='" + endTime + "'";
            //}

            //var usermodel = await _userAppService.GetByIdUserAsync(AbpSession.UserId.Value);
            //string sql = $@"select distinct b.FactoryinfoId,a.Restaurantid,RestaurantName,e.Id as DriverId,e.Name as DriverName,d.Name,Distributioncount,Backboxcount,Backnumbercount,Damagecount,Exchangegoodscount,Recoverycount,Givecount, Price,Sumprice from(select Restaurantid, TypeNumberInfoId, Sum(Distributioncount) as Distributioncount,Sum(Backboxcount) as Backboxcount,Sum(Backnumbercount) as Backnumbercount,Sum(Damagecount) as Damagecount,Sum(Exchangegoodscount) as Exchangegoodscount,Sum(Recoverycount) as Recoverycount,Sum(Givecount) as Givecount,Sum(Sumprice) as Sumprice from DistributionInfoDetails{where1}{where2} group by Restaurantid,TypeNumberInfoId) a,RestaurantInfo b,RestaurantTypenNumberInfo c,TypeNumberInfo d, AbpUsers e where a.Restaurantid = b.id and b.id = c.Restaurantid and a.TypeNumberInfoId = d.Id and b.EmployeeDriverid = e.Id and c.TypeNumberId=d.Id and b.FactoryinfoId = '{usermodel.FactoryinfoId}'";

            //var listmodel = _sqlExecuter.FromDapperSqlQuery<DistributionTypeNumberDto>(sql, null).AsQueryable();
            //if (!string.IsNullOrEmpty(restaurantName))
            //    listmodel = listmodel.Where(o => o.RestaurantName.Contains(restaurantName));
            //if (!string.IsNullOrEmpty(driverName))
            //    listmodel = listmodel.Where(o => o.DriverId.ToString() == driverName);
            #endregion

            var usermodel = await _userAppService.GetByIdUserAsync(AbpSession.UserId.Value);
            var listmodel = _repositoryDistributionInfoDetails.GetAllIncluding(o => o.RestaurantInfoModel, o => o.TypeNumberInfoModel).Where(o => o.RestaurantInfoModel.FactoryinfoId == usermodel.FactoryinfoId);
            if (beginTime.HasValue)
                listmodel = listmodel.Where(o => o.CreationTime >= beginTime);
            if (endTime.HasValue)
                listmodel = listmodel.Where(o => o.CreationTime <= endTime.Value.AddHours(24));

            var data = listmodel.GroupBy(o => new { o.Restaurantid, o.TypeNumberInfoId, o.TypeNumberName, o.TypeNumberPrice }).Select(s => new
            {
                s.Key.Restaurantid,
                s.Key.TypeNumberInfoId,
                s.Key.TypeNumberName,
                s.Key.TypeNumberPrice,
                Distributioncount = s.Sum(t => t.Distributioncount),
                DistributionNumbercount = s.Sum(t => t.Distributioncount * t.TypeNumberInfoModel.Count),
                Backboxcount = s.Sum(t => t.Backboxcount),
                Backnumbercount = s.Sum(t => t.Backnumbercount) + s.Sum(t => t.Backboxcount * t.TypeNumberInfoModel.Count),
                Damagecount = s.Sum(t => t.Damagecount),
                Exchangegoodscount = s.Sum(t => t.Exchangegoodscount),
                ExchangegoodsNumbercount = s.Sum(t => t.Exchangegoodscount * t.TypeNumberInfoModel.Count),
                Recoverycount = s.Sum(t => t.Recoverycount),
                RecoveryNumbercount = s.Sum(t => t.Recoverycount * t.TypeNumberInfoModel.Count),
                Givecount = s.Sum(t => t.Givecount),
                GiveNumbercount = s.Sum(t => t.Givecount * t.TypeNumberInfoModel.Count),
                Sumprice = s.Sum(t => t.Sumprice)

            }).Join(_repositoryRestaurantInfo.GetAllIncluding(o => o.EmployeeDriver), a => a.Restaurantid, b => b.Id, (a, b) => new DistributionTypeNumberDto
            {
                FactoryInfoId = b.FactoryinfoId.Value,
                RestaurantId = a.Restaurantid,
                RestaurantName = b.RestaurantName,
                DriverId = b.EmployeeDriverid,
                DriverName = b.EmployeeDriver.Name,
                Name = a.TypeNumberName,
                Distributioncount = a.Distributioncount,
                DistributionNumbercount = a.DistributionNumbercount,
                Backboxcount = a.Backboxcount,
                Backnumbercount = a.Backnumbercount,
                Damagecount = a.Damagecount,
                Exchangegoodscount = a.Exchangegoodscount,
                ExchangegoodsNumbercount = a.ExchangegoodsNumbercount,
                Recoverycount = a.Recoverycount,
                RecoveryNumbercount = a.RecoveryNumbercount,
                Givecount = a.Givecount,
                GiveNumbercount = a.GiveNumbercount,
                Price = a.TypeNumberPrice,
                Sumprice = a.Sumprice
            });

            if (!string.IsNullOrEmpty(restaurantName))
                data = data.Where(o => o.RestaurantName.Contains(restaurantName));
            if (driverName.HasValue)
                data = data.Where(o => o.DriverId == driverName);

            var list = data.GroupBy(o => new { o.RestaurantId, o.RestaurantName, o.FactoryInfoId, o.DriverId, o.DriverName }).Select(s => new DistributionTypeNumberReportDto
            {
                FactoryInfoId = s.Key.FactoryInfoId,
                RestaurantName = s.Key.RestaurantName,
                DriverId = s.Key.DriverId,
                DriverName = s.Key.DriverName,
                TypeNumberModelList = s.Select(t => new TypeNumberModel
                {
                    Name = t.Name,
                    Distributioncount = t.Distributioncount,
                    DistributionNumbercount = t.DistributionNumbercount,
                    Recoverycount = t.Recoverycount,
                    RecoveryNumbercount = t.RecoveryNumbercount,
                    Damagecount = t.Damagecount,
                    Backboxcount = t.Backboxcount,
                    Backnumbercount = t.Backnumbercount,
                    Exchangegoodscount = t.Exchangegoodscount,
                    ExchangegoodsNumbercount = t.ExchangegoodsNumbercount,
                    Givecount = t.Givecount,
                    GiveNumbercount = t.GiveNumbercount,
                    Price = t.Price,
                    Sumprice = t.Sumprice
                }).ToList()
            });

            return await list.ToPagedListAsync(pageIdx, pageSize);
        }

        public async Task<List<DistributionTypeNumberReportDto>> GetDistributionDetailsListsAsync(DateTime? beginTime, DateTime? endTime, string restaurantName, long? driverName)
        {
            
            var usermodel = await _userAppService.GetByIdUserAsync(AbpSession.UserId.Value);
            var listmodel = _repositoryDistributionInfoDetails.GetAllIncluding(o => o.RestaurantInfoModel, o => o.TypeNumberInfoModel).Where(o => o.RestaurantInfoModel.FactoryinfoId == usermodel.FactoryinfoId);
            if (beginTime.HasValue)
                listmodel = listmodel.Where(o => o.CreationTime >= beginTime);
            if (endTime.HasValue)
                listmodel = listmodel.Where(o => o.CreationTime <= endTime.Value.AddHours(24));

            var data = listmodel.GroupBy(o => new { o.Restaurantid, o.TypeNumberInfoId, o.TypeNumberName, o.TypeNumberPrice }).Select(s => new
            {
                s.Key.Restaurantid,
                s.Key.TypeNumberInfoId,
                s.Key.TypeNumberName,
                s.Key.TypeNumberPrice,
                Distributioncount = s.Sum(t => t.Distributioncount),
                DistributionNumbercount = s.Sum(t => t.Distributioncount * t.TypeNumberInfoModel.Count),
                Backboxcount = s.Sum(t => t.Backboxcount),
                Backnumbercount = s.Sum(t => t.Backnumbercount) + s.Sum(t => t.Backboxcount * t.TypeNumberInfoModel.Count),
                Damagecount = s.Sum(t => t.Damagecount),
                Exchangegoodscount = s.Sum(t => t.Exchangegoodscount),
                ExchangegoodsNumbercount = s.Sum(t => t.Exchangegoodscount * t.TypeNumberInfoModel.Count),
                Recoverycount = s.Sum(t => t.Recoverycount),
                RecoveryNumbercount = s.Sum(t => t.Recoverycount * t.TypeNumberInfoModel.Count),
                Givecount = s.Sum(t => t.Givecount),
                GiveNumbercount = s.Sum(t => t.Givecount * t.TypeNumberInfoModel.Count),
                Sumprice = s.Sum(t => t.Sumprice)

            }).Join(_repositoryRestaurantInfo.GetAllIncluding(o => o.EmployeeDriver), a => a.Restaurantid, b => b.Id, (a, b) => new DistributionTypeNumberDto
            {
                FactoryInfoId = b.FactoryinfoId.Value,
                RestaurantId = a.Restaurantid,
                RestaurantName = b.RestaurantName,
                DriverId = b.EmployeeDriverid,
                DriverName = b.EmployeeDriver.Name,
                Name = a.TypeNumberName,
                Distributioncount = a.Distributioncount,
                DistributionNumbercount = a.DistributionNumbercount,
                Backboxcount = a.Backboxcount,
                Backnumbercount = a.Backnumbercount,
                Damagecount = a.Damagecount,
                Exchangegoodscount = a.Exchangegoodscount,
                ExchangegoodsNumbercount = a.ExchangegoodsNumbercount,
                Recoverycount = a.Recoverycount,
                RecoveryNumbercount = a.RecoveryNumbercount,
                Givecount = a.Givecount,
                GiveNumbercount = a.GiveNumbercount,
                Price = a.TypeNumberPrice,
                Sumprice = a.Sumprice
            });

            if (!string.IsNullOrEmpty(restaurantName))
                data = data.Where(o => o.RestaurantName.Contains(restaurantName));
            if (driverName.HasValue)
                data = data.Where(o => o.DriverId == driverName);

            var list = data.GroupBy(o => new { o.RestaurantId, o.RestaurantName, o.FactoryInfoId, o.DriverId, o.DriverName }).Select(s => new DistributionTypeNumberReportDto
            {
                FactoryInfoId = s.Key.FactoryInfoId,
                RestaurantName = s.Key.RestaurantName,
                DriverId = s.Key.DriverId,
                DriverName = s.Key.DriverName,
                TypeNumberModelList = s.Select(t => new TypeNumberModel
                {
                    Name = t.Name,
                    Distributioncount = t.Distributioncount,
                    DistributionNumbercount = t.DistributionNumbercount,
                    Recoverycount = t.Recoverycount,
                    RecoveryNumbercount = t.RecoveryNumbercount,
                    Damagecount = t.Damagecount,
                    Backboxcount = t.Backboxcount,
                    Backnumbercount = t.Backnumbercount,
                    Exchangegoodscount = t.Exchangegoodscount,
                    ExchangegoodsNumbercount = t.ExchangegoodsNumbercount,
                    Givecount = t.Givecount,
                    GiveNumbercount = t.GiveNumbercount,
                    Price = t.Price,
                    Sumprice = t.Sumprice
                }).ToList()
            });

            return list.ToList();
        }
        /// <summary>
        /// 导出
        /// </summary>
        /// <returns></returns>
        public async Task<List<DistributionTypeNumberReportDto>> GetExportDistributionDetailsAsync(string restaurantName, string driverName, DateTime? beginTime, DateTime? endTime)
        {
            var usermodel = await _userAppService.GetByIdUserAsync(AbpSession.UserId.Value);

            var listmodel = _repositoryDistributionInfoDetails.GetAllIncluding(o => o.RestaurantInfoModel).Where(o => o.RestaurantInfoModel.FactoryinfoId == usermodel.FactoryinfoId);
            if (beginTime.HasValue)
                listmodel = listmodel.Where(o => o.CreationTime >= beginTime);
            if (endTime.HasValue)
                listmodel = listmodel.Where(o => o.CreationTime <= endTime.Value.AddHours(24));

            var data = listmodel.GroupBy(o => new { o.Restaurantid, o.TypeNumberInfoId, o.TypeNumberName, o.TypeNumberPrice }).Select(s => new
            {
                s.Key.Restaurantid,
                s.Key.TypeNumberInfoId,
                s.Key.TypeNumberName,
                s.Key.TypeNumberPrice,
                Distributioncount = s.Sum(t => t.Distributioncount),
                DistributionNumbercount = s.Sum(t => t.Distributioncount * t.TypeNumberInfoModel.Count),
                Backboxcount = s.Sum(t => t.Backboxcount),
                Backnumbercount = s.Sum(t => t.Backnumbercount),
                Damagecount = s.Sum(t => t.Damagecount),
                Exchangegoodscount = s.Sum(t => t.Exchangegoodscount),
                ExchangegoodsNumbercount = s.Sum(t => t.Exchangegoodscount * t.TypeNumberInfoModel.Count),
                Recoverycount = s.Sum(t => t.Recoverycount),
                RecoveryNumbercount = s.Sum(t => t.Recoverycount * t.TypeNumberInfoModel.Count),
                Givecount = s.Sum(t => t.Givecount),
                GiveNumbercount = s.Sum(t => t.Givecount * t.TypeNumberInfoModel.Count),
                Sumprice = s.Sum(t => t.Sumprice)

            }).Join(_repositoryRestaurantInfo.GetAllIncluding(o => o.EmployeeDriver), a => a.Restaurantid, b => b.Id, (a, b) => new DistributionTypeNumberDto
            {
                FactoryInfoId = b.FactoryinfoId.Value,
                RestaurantId = a.Restaurantid,
                RestaurantName = b.RestaurantName,
                DriverId = b.EmployeeDriverid,
                DriverName = b.EmployeeDriver.Name,
                Name = a.TypeNumberName,
                Distributioncount = a.Distributioncount,
                DistributionNumbercount = a.DistributionNumbercount,
                Backboxcount = a.Backboxcount,
                Backnumbercount = a.Backnumbercount,
                Damagecount = a.Damagecount,
                Exchangegoodscount = a.Exchangegoodscount,
                ExchangegoodsNumbercount = a.ExchangegoodsNumbercount,
                Recoverycount = a.Recoverycount,
                RecoveryNumbercount = a.RecoveryNumbercount,
                Givecount = a.Givecount,
                GiveNumbercount = a.GiveNumbercount,
                Price = a.TypeNumberPrice,
                Sumprice = a.Sumprice
            });

            if (!string.IsNullOrEmpty(restaurantName))
                data = data.Where(o => o.RestaurantName.Contains(restaurantName));
            if (!string.IsNullOrEmpty(driverName))
                data = data.Where(o => o.DriverId.ToString() == driverName);
            var list = data.GroupBy(o => new { o.RestaurantId, o.RestaurantName, o.FactoryInfoId, o.DriverId, o.DriverName }).Select(s => new DistributionTypeNumberReportDto
            {
                FactoryInfoId = s.Key.FactoryInfoId,
                RestaurantName = s.Key.RestaurantName,
                DriverId = s.Key.DriverId,
                DriverName = s.Key.DriverName,
                TypeNumberModelList = s.Select(t => new TypeNumberModel
                {
                    Name = t.Name,
                    Distributioncount = t.Distributioncount,
                    Recoverycount = t.Recoverycount,
                    Damagecount = t.Damagecount,
                    Backboxcount = t.Backboxcount,
                    Backnumbercount = t.Backnumbercount,
                    Exchangegoodscount = t.Exchangegoodscount,
                    Givecount = t.Givecount,
                    Price = t.Price,
                    Sumprice = t.Sumprice
                }).ToList()
            });

            return list.ToList();
        }
        /// <summary>
        /// 应收汇总
        /// </summary>
        /// <returns></returns>
        public async Task<IPagedList<ReceivableSummaryListDto>> GetReceivableSummaryListAsync(int pageIdx, int pageSize, DateTime? beginTime, DateTime? endTime)
        {



            //var data = _repositoryDistributionInfo.GetAllIncluding(o => o.DistributionInfoListDetails);
            //if (beginTime.HasValue)
            //    data = data.Where(o => o.CreationTime >= beginTime);
            //if (endTime.HasValue)
            // data = data.Where(o => o.CreationTime <= endTime.Value.AddHours(24));






            var model = _repositoryDistributionInfoDetails.GetAllIncluding(o => o.DistributionInfoModel);
            var data = model.Join(_repositoryRestaurantInfo.GetAll(), a => a.Restaurantid, b => b.Id, (a, b) => new
            {
                b.Id,
                b.RestaurantName,
                a.Distributioncount,
                a.Givecount,
                a.Exchangegoodscount,
                a.Damagecount,
                a.Backboxcount,
                a.Backnumbercount,
                a.Recoverycount,
                a.TypeNumberInfoId,
                a.TypeNumberName,
                a.TypeNumberPrice,
                DistributionInfoId = a.DistributionInfoModel.Id,
                a.DistributionInfoModel.SettlementId,
                a.DistributionInfoModel.TotalPrice,
                a.DistributionInfoModel.CreationTime,
                a.Sumprice,
            }).Join(_repositoryTypeNumber.GetAll(), a => a.TypeNumberInfoId, b => b.Id, (a, b) => new
            {
                a.Id,
                a.RestaurantName,
                DistributionBoxCount = a.Distributioncount,
                DistributionCount = a.Distributioncount * b.Count,
                GiveBoxCount = a.Givecount,
                GiveCount = a.Givecount * b.Count,
                ExchangeBoxCount = a.Exchangegoodscount,
                ExchangeCount = a.Exchangegoodscount * b.Count,
                a.Damagecount,
                a.Backboxcount,
                a.Backnumbercount,
                RecoveryCount = a.Recoverycount,
                RecoveryBoxCount = a.Recoverycount * b.Count,
                a.TypeNumberName,
                a.TypeNumberPrice,
                a.SettlementId,
                a.DistributionInfoId,
                a.TotalPrice,
                a.CreationTime,
                a.Sumprice
            }).Join(_repositorySettlement.GetAll(), a => a.SettlementId, b => b.Id, (a, b) => new ReceivableSummaryDto
            {
                DisId = a.DistributionInfoId,
                RestaurantName = a.RestaurantName,
                DistributionDate = a.CreationTime,
                DistributionPrice = a.TotalPrice,
                SumDiscountprice = b.Discountprice,
                TotalPrice = b.Totalprice,
                UncollectedPrice = b.Totalprice,
                TypeNumberName = a.TypeNumberName,
                DistributionBoxCount = a.DistributionBoxCount,
                DistributionCount = a.DistributionCount,
                RecoveryBoxCount = a.RecoveryBoxCount,
                RecoveryCount = a.RecoveryCount,
                GiveBoxCount = a.GiveBoxCount,
                GiveCount = a.GiveCount,
                ExChangeBoxCount = a.ExchangeBoxCount,
                ExChangeCount = a.ExchangeCount,
                BackBoxCount = a.Backboxcount,
                BackCount = a.Backnumbercount,
                DamageCount = a.Damagecount,
                UnitPrice = a.TypeNumberPrice,
                Price = a.Sumprice
            });

            if (beginTime.HasValue)
                data = data.Where(o => o.DistributionDate >= beginTime);
            if (endTime.HasValue)
                data = data.Where(o => o.DistributionDate <= endTime.Value.AddHours(24));

            var list = data.GroupBy(o => o.DisId);

            List<ReceivableSummaryListDto> listDto = new List<ReceivableSummaryListDto>();

            foreach (var item in list)
            {
                ReceivableSummaryListDto dto = new ReceivableSummaryListDto();
                if (item.Count() > 0)
                {
                    dto.DistributionInfoId = item.Key;
                    dto.RestaurantName = item.First().RestaurantName;
                    dto.DistributionDate = item.First().DistributionDate;
                    dto.SumDiscountprice = item.First().SumDiscountprice;
                    dto.DistributionPrice = item.First().DistributionPrice;
                    dto.TotalPrice = item.First().TotalPrice;
                    dto.UncollectedPrice = item.First().UncollectedPrice;
                    dto.TypeNumberList = new List<TypeNumberInfoList>();

                    foreach (var temp in item)
                    {
                        TypeNumberInfoList typeNumberModel = new TypeNumberInfoList()
                        {
                            TypeNumberName = temp.TypeNumberName,
                            DistributionBoxCount = temp.DistributionBoxCount,
                            DistributionCount = temp.DistributionCount,
                            RecoveryBoxCount = temp.RecoveryBoxCount,
                            RecoveryCount = temp.RecoveryCount,
                            ExChangeBoxCount = temp.ExChangeBoxCount,
                            ExChangeCount = temp.ExChangeCount,
                            GiveBoxCount = temp.GiveBoxCount,
                            GiveCount = temp.GiveCount,
                            BackBoxCount = temp.BackBoxCount,
                            BackCount = temp.BackCount,
                            DamageCount = temp.BackCount,
                            UnitPrice = temp.UnitPrice,
                            Price = temp.Price
                        };
                        dto.TypeNumberList.Add(typeNumberModel);
                    }
                }
                listDto.Add(dto);
            }

            return await listDto.OrderByDescending(o => o.DistributionDate).ToPagedListAsync(pageIdx, pageSize);
        }

        private Task<List<DistributionInfoDetails>> GetCache
        {
            get
            {
                //var lis1t = _repositoryDistributionInfoDetails.GetAll().ToList();
                //var list = _repositoryDistributionInfoDetails.GetAllIncluding(o => o.RestaurantTypenNumberInfoModel, o => o.RestaurantInfoModel).ToList();
                var user = Task.Run(() => GetCurrentUserAsync()).Result;
                ICache cache = _catchmanager.GetCache(nameof(DistributionInfoDetails));
                return cache.GetAsync($"list", async () => await _repositoryDistributionInfoDetails.GetAllIncluding(o => o.RestaurantTypenNumberInfoModel, o => o.RestaurantInfoModel).ToListAsync());
            }

        }
    }
}
